#include "TextureManager.h"
#include "../../Game/Definitions.h"
#include <math.h>
#include "../D3D9Renderer.h"
#include "../../Utility/Misc/DebugOutput.h"

vector<IDirect3DTexture9*>	TextureManager::textures;

int TextureManager::LoadTexture(string _fileName)
{
	IDirect3DTexture9* texture;
	D3DXIMAGE_INFO srcInfo;

	D3DCOLOR colorKey = 0xFFFF00FF;

	if(FAILED(D3DXCreateTextureFromFileEx(D3D9Renderer::device, _fileName.c_str(), 0, 0, 1, 0,
		D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,
		colorKey, &srcInfo, NULL, &texture)))
	{
#ifdef _DEBUG
		DebugOutput::Print(DebugOutput::RENDER_MSG, DebugOutput::FAILURE_CREATE ,"FAILED LOADING OF TEXTURE");
#endif
		return -1;
	}
	else
	{
		textures.push_back(texture);
	}

	return textures.size() - 1;
}

void TextureManager::Shutdown()
{
	for(unsigned int i = 0; i < textures.size(); ++i)
	{
		ReleaseCOM(textures[i]);
	}

	textures.clear();
}

void TextureManager::DrawTexture(int _textureID, int _posX, int _posY, float _scaleX, float _scaleY, float _rotate)
{
	IDirect3DTexture9* texture = textures[_textureID];
	D3DSURFACE_DESC textureData;
	if(FAILED(texture->GetLevelDesc(0, &textureData)))
	{
#ifdef _DEBUG
		DebugOutput::Print(DebugOutput::RENDER_MSG, DebugOutput::FAILURE_CREATE ,"FAILED TO GET TEXTURE DATA");
#endif
	}

	int halfHeight = (int)((textureData.Height * _scaleY) / 2);
	int halfWidth = (int)((textureData.Width * _scaleX) / 2);

	float X;
	float Y;
	D3DXMATRIX matTranslation;
	D3DXMATRIX matScaling;
	D3DXMATRIX matTransform;
	D3DXMatrixIdentity(&matTranslation);
	D3DXMatrixIdentity(&matScaling);
	D3DXMatrixIdentity(&matTransform);

// 	if(_rotate)
// 	{
// 		_posY += (textureData.Height / (PI / _rotate));
// 	}

	//Get coordinates
	RECT rDest;
	rDest.top = _posY - (halfHeight);
	rDest.bottom = _posY + (halfHeight);
	rDest.left = _posX - (halfWidth);
	rDest.right = _posX + (halfWidth);
	//rDest.top = 0;
	//rDest.bottom = 256;
	//rDest.left = 0;
	//rDest.right = 256;

	//X = rDest.left - (float)(D3D9Renderer::pp.BackBufferWidth) / 2;
	//Y = -rDest.top + (float)(D3D9Renderer::pp.BackBufferHeight) / 2;
	X = (float)-halfWidth;
	Y = (float)halfHeight;

	//Setup translation and scaling matrices
	D3DXMatrixScaling (&matScaling, (float)(rDest.right - rDest.left),
		(float)(rDest.bottom - rDest.top), 1.0f);

	//D3DXMatrixTranslation (&matTranslation, -128.0f, 128.0f, 0.0f);
	D3DXMatrixTranslation (&matTranslation, X, Y, 0.0f);

	D3DXMATRIX newTranslation;
	float halfBufferWidth = D3D9Renderer::pp.BackBufferWidth / 2.0f;
	float halfBufferHeight = D3D9Renderer::pp.BackBufferHeight / 2.0f;
	float newX = (((halfBufferWidth * -1) + _posX) - X) - halfWidth;
	float newY = ((halfBufferHeight - _posY) + Y) - halfHeight;

	//D3DXMatrixTranslation (&newTranslation, -172.0f - 128.0f, 72.0f + 128.0f, 0.0f);
	D3DXMatrixTranslation (&newTranslation, newX, newY, 0.0f);

	//matTransform = matScaling * matTranslation;

	//Check if quad is rotated
	if (_rotate)
	{
		D3DXMATRIX matRotate;
		D3DXMatrixIdentity(&matRotate);
		//Create rotation matrix about the z-axis
		D3DXMatrixRotationZ (&matRotate, _rotate);

		//Multiply matrices together
		matTransform = matScaling * matTranslation * matRotate * newTranslation;
		//matTransform = matScaling * matRotate * matTranslation;
	}
	else
	{
		//D3DXMatrixIdentity(&matScaling);
		matTransform = matScaling * matTranslation * newTranslation;
	}

	//Draw the quad
	D3D9Renderer::device->SetTransform (D3DTS_WORLD, &matTransform);
	D3D9Renderer::device->SetTexture (0, texture);
	D3D9Renderer::device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}

void TextureManager::DrawTexture(	int _textureID, int _posX, int _posY,
									float _scaleX, float _scaleY, RECT* _selectionRect, 
									float _rotCenterX, float _rotCenterY, float _rotation, DWORD _color)
{
	D3D9Renderer::BeginSprite();

	IDirect3DTexture9* texture = textures[_textureID];
	D3DSURFACE_DESC textureData;
	if(FAILED(texture->GetLevelDesc(0, &textureData)))
	{
#ifdef _DEBUG
		DebugOutput::Print(DebugOutput::RENDER_MSG, DebugOutput::FAILURE_CREATE ,"FAILED TO GET TEXTURE DATA");
#endif
	}

	int halfHeight = (int)((textureData.Height * _scaleY) / 2);
	int halfWidth = (int)((textureData.Width * _scaleX) / 2);

	D3DXMATRIX scale;
	D3DXMATRIX rotation;
	D3DXMATRIX translate;
	D3DXMATRIX combined;

	D3DXMatrixIdentity(&combined);

	D3DXMatrixScaling(&scale, _scaleX, _scaleY, 1.0f);
	combined *= scale;

	D3DXMatrixTranslation(&translate, -_rotCenterX * _scaleX, -_rotCenterY * _scaleY, 0.0f);
	combined *= translate;
	
	//CONVERT DEGREES TO RADIANS
	_rotation *= (PI / 180.0f);

	D3DXMatrixRotationZ(&rotation, -_rotation);
	combined *= rotation;

	D3DXMatrixTranslation(&translate, _rotCenterX * _scaleX, _rotCenterY * _scaleY, 0.0f);
	combined *= translate;

	D3DXMatrixTranslation(&translate, (float)_posX - halfWidth, (float)_posY - halfHeight, 0.0f);
	combined *= translate;

	D3D9Renderer::spriteDevice->SetTransform(&combined);

	D3D9Renderer::spriteDevice->Draw(textures[_textureID], _selectionRect, NULL, NULL, _color);

	D3DXMatrixIdentity(&combined);
	D3D9Renderer::spriteDevice->SetTransform(&combined);

	D3D9Renderer::EndSprite();
}